package com.gzhryc.shared_device.oem.micro.queue;

import java.sql.SQLException;
import java.util.Date;

import com.gzhryc.common.DateTools;
import com.gzhryc.common.StringTools;
import com.gzhryc.common.exceptions.LogicException;
import com.gzhryc.common.json.JsonTools;
import com.gzhryc.common.kafka.JFKafkaProducer;
import com.gzhryc.common.kafka.KafkaProducerFactory;
import com.gzhryc.common.kafka.models.KafkaMessage;
import com.gzhryc.common.logging.Logger;
import com.gzhryc.jdbc.JdbcSession;
import com.gzhryc.jdbc.utils.ClassTools;
import com.gzhryc.shared_device.base.enums.ELogState;
import com.gzhryc.shared_device.base.models.OperateInfo;
import com.gzhryc.shared_device.cdcz.code.dao.db.CDCZOrder;
import com.gzhryc.shared_device.cdcz.code.services.CDCZOrderLogService;
import com.gzhryc.shared_device.cdcz.code.services.CDCZOrderService;
import com.gzhryc.shared_device.cdcz.core.ICDCZNetworkService;
import com.gzhryc.shared_device.oem.code.HttpNetworkServiceUtils;
import com.gzhryc.shared_device.oem.code.KafkaEventConstants;
import com.gzhryc.shared_device.oem.code.PayServiceFactory;
import com.gzhryc.shared_device.oem.code.business.EBusinessType;
import com.gzhryc.shared_device.oem.code.device.EDeviceFunCode;
import com.gzhryc.shared_device.oem.code.member.services.MemberBusinessOrderService;
import com.gzhryc.shared_device.oem.code.member.services.MemberWalletService;
import com.gzhryc.shared_device.oem.code.order.RedisCacheManager;
import com.gzhryc.shared_device.oem.code.order.event.OrderCancelEvent;
import com.gzhryc.shared_device.oem.code.order.event.OrderFinishEvent;
import com.gzhryc.shared_device.oem.code.place.services.PlaceBusinessConfigService;
import com.gzhryc.shared_device.oem.code.profit.service.BusinessOrderService;

public class CDCZOrderOperateHelper {
	
	 static Logger log = Logger.getLogger(CDCZOrderOperateHelper.class);

	 /**
	  * 检查使用时间是否到期，如果订单到期则订单完成
	  * @param deviceOrder
	  * @param operateInfo
	  * @throws LogicException
	  */
	public static void chekcTimeOrToFinish(CDCZOrder deviceOrder,OperateInfo operateInfo) throws LogicException {
		if(deviceOrder != null){
            if(deviceOrder.getEndDate() == null){
                Long times = DateTools.differenceMinute(deviceOrder.getCreateDate(),new Date());
                if(times > 13){  //13分钟
                    //清理缓存，避免定时器重复处理
                    RedisCacheManager.removeWorkingCDCZDeviceOrder(deviceOrder.getTradeNo());

                    ICDCZNetworkService networkService = HttpNetworkServiceUtils.getCDCZNetworkService(deviceOrder.getIotId());
                    boolean synCancel = false;
                    Date cancelDate = new Date();
                    Long incomeMoney = deviceOrder.getIncomeMoney();
                    operateInfo.setOperateNote("无结束时间订单，撤销处理");
                    Integer result = CDCZOrderService.self(deviceOrder.getCreateDate()).cancel(deviceOrder, PayServiceFactory.self(), networkService, operateInfo);
                    if (result > 0) {
                        synCancel = true;
                    } else {
                        log.error("撤销充电插座订单失败，订单信息：{{0:json}}", deviceOrder);
                    }

                    if(synCancel){
                        deviceOrder = CDCZOrderService.self(deviceOrder.getCreateDate()).getByTradeNo(deviceOrder.getTradeNo());
                        
                        MemberBusinessOrderService.self(deviceOrder.getCreateDate()).cancel(deviceOrder.getTradeNo()
                                ,deviceOrder.getMoney(),deviceOrder.getPayMoney(),deviceOrder.getWalletMoney());
                       
                        BusinessOrderService.self(deviceOrder.getCreateDate()).cancel(deviceOrder.getTradeNo(),cancelDate);
                        JFKafkaProducer producer = KafkaProducerFactory.self().getProducer();
                        if (producer != null) {
                            OrderCancelEvent event = new OrderCancelEvent(EDeviceFunCode.CDCZ.index(),deviceOrder.getTradeNo()
                                    ,deviceOrder.getCreateDate(),incomeMoney,cancelDate);
                            KafkaMessage kafkaMessage = new KafkaMessage(KafkaEventConstants.TOPIC_Order,
                                    KafkaEventConstants.KEY_OrderCancel, JsonTools.toJson(event));
                            producer.send(kafkaMessage);
                        }
                    }
                }
            }else {
                Long times = DateTools.differenceMinute(new Date(), deviceOrder.getEndDate());
                if (times <= 0) {
                    //清理缓存，避免定时器重复处理
                    RedisCacheManager.removeWorkingCDCZDeviceOrder(deviceOrder.getTradeNo());
                    //获取功率区间的收费金额
                    Long payMoney = PlaceBusinessConfigService.self().getCDCZPayMoney(deviceOrder.getPlaceId(),deviceOrder.getMaxUsePower());
                    //计算最后支付金额
                    Long walletMoney = CDCZOrderService.self(deviceOrder.getCreateDate()).computePayMoney(deviceOrder, payMoney);
                    //获取设备通信服务 
                    ICDCZNetworkService networkService = HttpNetworkServiceUtils.getCDCZNetworkService(deviceOrder.getIotId());
                    
                    Integer operateState = ELogState.Fail.index();
                    String errorMsg = null;
                    operateInfo.setOperateNote("订单到时完成");
                    
                    JdbcSession.begin();
                    try {
                    	Long debtMoney = 0L;
                    	if(walletMoney > 0) {
                    		OperateInfo walletOperateInfo = ClassTools.copy(new OperateInfo(), operateInfo);
                    		walletOperateInfo.setOperateNote(deviceOrder.getTradeNo() + "订单最后扣费");
                             Long reduceMoney = MemberWalletService.self().reduceFaceMoney(deviceOrder.getMemberId(), walletMoney, walletOperateInfo);
                           	 if(reduceMoney  < walletMoney) {
                           		 //订单欠费，记录欠费金额
                           		debtMoney = walletMoney - reduceMoney;
                           		walletMoney = reduceMoney;
                             }
                    	}
                    	
                        if(CDCZOrderService.self(deviceOrder.getCreateDate()).timesFillToFinish(deviceOrder, payMoney, walletMoney, debtMoney, networkService
                        		, operateInfo)){
                        	JdbcSession.commit();
                        	operateState = ELogState.Success.index();
                        }else{
                            log.error("完成充电插座订单失败，订单信息：{{0:json}}", deviceOrder);
                        }
                    } catch (SQLException e) {
                        log.error(e.getMessage(), e);
                        errorMsg = e.getMessage();
                    } catch (LogicException e) {
                        log.error(e.getMessage(), e);
                        errorMsg = e.getMessage();
                    } finally {
                        JdbcSession.end();
                    }
                
                    if (ELogState.Success.index().equals(operateState)) {
                        deviceOrder = CDCZOrderService.self(deviceOrder.getCreateDate()).getByTradeNo(deviceOrder.getTradeNo());
                        MemberBusinessOrderService.self(deviceOrder.getCreateDate()).finish(deviceOrder.getTradeNo(), deviceOrder.getMoney(), deviceOrder.getPayMoney()
                                ,deviceOrder.getWalletMoney(),operateInfo);
                        
                        JFKafkaProducer producer = KafkaProducerFactory.self().getProducer();
                        if (producer != null) {
                            OrderFinishEvent event = new OrderFinishEvent(EBusinessType.CDCZ.index(), deviceOrder.getTradeNo(),deviceOrder.getCreateDate(),operateInfo);
                            KafkaMessage kafkaMessage = new KafkaMessage(KafkaEventConstants.TOPIC_Order, KafkaEventConstants.KEY_OrderFinish, JsonTools.toJson(event));
                            producer.send(kafkaMessage);
                        }
                    }else if(StringTools.isNotBlank(errorMsg)){
                    	 //记录日志
                        CDCZOrderLogService.self(deviceOrder.getCreateDate()).add(deviceOrder, operateInfo, operateState, errorMsg);
                    }
                }
            }
        }
    }
}
